﻿using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web.Helpers;
using System.Web.Mvc;
using Website.Models;

namespace Website.Controllers
{ 
    public class ProductController : Controller
    {
        private KFashionEntities db = new KFashionEntities();

        //
        // GET: /Product/

        public ViewResult Index(string productCode)
        {
            var products = db.Products.Include("Category").Include("PriceLevel").OrderByDescending(p => p.ProductID).ToList();
            if(!string.IsNullOrEmpty(productCode))
            {
                products = products.Where(p => p.ProductCode.Contains(productCode)).ToList();
                ViewBag.ProductCode = productCode;
            }
            return View(products.ToList());
        }

        //
        // GET: /Product/Details/5

        public ViewResult Details(int id)
        {
            Product product = db.Products.Single(p => p.ProductID == id);
            return View(product);
        }

        //
        // GET: /Product/Create

        public ActionResult Create()
        {
            ViewBag.Categories = db.Categories.Where(c => !c.ParentCategoryID.HasValue);
            ViewBag.PriceLevels = db.PriceLevels;
            Product p = new Product();
            foreach (Size size in db.Sizes)
            {
                var ps = new ProductSize {SizeID = size.SizeID, Size = size};
                p.ProductSizes.Add(ps);
            }
            return View(p);
        }
 
        //
        // POST: /Product/Create

        [HttpPost]
        public ActionResult Create(Product product)
        {
            #region ProductCode
/*            var selectedCategory = db.Categories.Single(c => c.CategoryID == product.CategoryID);
            string productCode = selectedCategory.Gender ? "M-" : "F-";
            productCode += selectedCategory.Code + "-";
            var selectedPriceLevel = db.PriceLevels.Single(p => p.PriceLevelID == product.PriceLevelID);
            productCode += selectedPriceLevel.PriceLevelCode + "-";
            int index = db.Products.Count() + 1;
            int zeroCount = 4 - index.ToString().Length;
            string indexCode = "";
            for (int i = 0; i < zeroCount; i++)
            {
                indexCode += "0";
            }
            indexCode += index.ToString();
            productCode += indexCode;
            product.ProductCode = productCode;*/ 
            #endregion

            #region Images

            WebImage mainImage = new WebImage(Request.Files["MainImage"].InputStream);
            string mainImagePath = string.Format("/Images/Product/{0}.jpg", product.ProductCode);
            mainImage.Save(Server.MapPath(mainImagePath));
            product.MainImage = "~" + mainImagePath;

            WebImage smallImage = mainImage.Resize(400, 800);
            string smallImagePath = string.Format("/Images/Product/Small/{0}.jpg", product.ProductCode);
            smallImage.Save(Server.MapPath(smallImagePath));
            product.SmallImage = "~" + smallImagePath;

            if (Request.Files["SubImage1"] != null && Request.Files["SubImage1"].InputStream.Length > 0)
            {
                WebImage subImage1 = new WebImage(Request.Files["SubImage1"].InputStream);
                string subImage1Path = string.Format("/Images/Product/{0}-1.jpg", product.ProductCode);
                subImage1.Save(Server.MapPath(subImage1Path));
                product.SubImage1 = "~" + subImage1Path;
            }

            if (Request.Files["SubImage2"] != null && Request.Files["SubImage2"].InputStream.Length > 0)
            {
                WebImage subImage2 = new WebImage(Request.Files["SubImage2"].InputStream);
                string subImage2Path = string.Format("/Images/Product/{0}-2.jpg", product.ProductCode);
                subImage2.Save(Server.MapPath(subImage2Path));
                product.SubImage2 = "~" + subImage2Path;
            }

            if (Request.Files["SubImage3"] != null && Request.Files["SubImage3"].InputStream.Length > 0)
            {
                WebImage subImage3 = new WebImage(Request.Files["SubImage3"].InputStream);
                string subImage3Path = string.Format("/Images/Product/{0}-3.jpg", product.ProductCode);
                subImage3.Save(Server.MapPath(subImage3Path));
                product.SubImage3 = "~" + subImage3Path;
            }

            #endregion

            #region Price
            if(product.Price != null)
                product.PriceLevelID = null;
            else
            {
                if(!product.PriceLevelID.HasValue)
                    ModelState.AddModelError("PriceLevelID", "You must choose PriceLevel or enter Price");
            }
            #endregion

            if (ModelState.IsValid)
            {
                db.Products.AddObject(product);
                db.SaveChanges();
                #region Add Product Size
                var sizeIDs = Request.Params["ProductSizes.ps.SizeID"].Split(',');
                var quantities = Request.Params["ProductSizes.ps.Quantity"].Split(',');
                for (int i = 0; i < sizeIDs.Length; i++)
                {
                    if(int.Parse(quantities[i]) == 0) continue;
                    ProductSize ps = new ProductSize { SizeID = int.Parse(sizeIDs[i]), Quantity = int.Parse(quantities[i]) };
                    product.ProductSizes.Add(ps);
                }
                db.SaveChanges();
                #endregion
                return RedirectToAction("Index");  
            }

            ViewBag.Categories = db.Categories.Where(c => !c.ParentCategoryID.HasValue);
            ViewBag.CurrentCategoryID = product.CategoryID;
            return View(product);
        }
        
        //
        // GET: /Product/Edit/5
 
        public ActionResult Edit(int id)
        {
            Product product = db.Products.Include("Category").Include("PriceLevel").Single(p => p.ProductID == id);
//            ViewBag.CategoryID = new SelectList(db.Categories, "CategoryID", "CategoryName", product.CategoryID);
            ViewBag.CurrentCategoryID = product.CategoryID;
            if (product.PriceLevelID.HasValue)
                ViewBag.PriceLevelID = product.PriceLevelID;
            ViewBag.PriceLevels = db.PriceLevels;
            ViewBag.Categories = db.Categories.Where(c => !c.ParentCategoryID.HasValue);
            return View(product);
        }

        //
        // POST: /Product/Edit/5

        [HttpPost]
        public ActionResult Edit(Product product)
        {
            #region Images
            if (Request.Files["MainImage"] != null && Request.Files["MainImage"].InputStream.Length > 0)
            {
                WebImage mainImage = new WebImage(Request.Files["MainImage"].InputStream);
                string mainImagePath = string.Format("/Images/Product/{0}.jpg", product.ProductCode);
                mainImage.Save(Server.MapPath(mainImagePath));
                product.MainImage = "~" + mainImagePath;
            }
            if (Request.Files["SmallImage"] != null && Request.Files["SmallImage"].InputStream.Length > 0)
            {
                WebImage smallImage = new WebImage(Request.Files["SmallImage"].InputStream).Resize(400, 800);
                string smallImagePath = string.Format("/Images/Product/Small/{0}.jpg", product.ProductCode);
                smallImage.Save(Server.MapPath(smallImagePath));
                product.SmallImage = "~" + smallImagePath;
            }
            if (Request.Files["SubImage1"] != null && Request.Files["SubImage1"].InputStream.Length > 0)
            {
                WebImage subImage1 = new WebImage(Request.Files["SubImage1"].InputStream);
                string subImage1Path = string.Format("/Images/Product/{0}-1.jpg", product.ProductCode);
                subImage1.Save(Server.MapPath(subImage1Path));
                product.SubImage1 = "~" + subImage1Path;
            }
            if (Request.Files["SubImage2"] != null && Request.Files["SubImage2"].InputStream.Length > 0)
            {
                WebImage subImage2 = new WebImage(Request.Files["SubImage2"].InputStream);
                string subImage2Path = string.Format("/Images/Product/{0}-2.jpg", product.ProductCode);
                subImage2.Save(Server.MapPath(subImage2Path));
                product.SubImage2 = "~" + subImage2Path;
            }
            if (Request.Files["SubImage3"] != null && Request.Files["SubImage3"].InputStream.Length > 0)
            {
                WebImage subImage3 = new WebImage(Request.Files["SubImage3"].InputStream);
                string subImage3Path = string.Format("/Images/Product/{0}-3.jpg", product.ProductCode);
                subImage3.Save(Server.MapPath(subImage3Path));
                product.SubImage3 = "~" + subImage3Path;
            }            
            #endregion

            if (product.Price.HasValue)
                product.PriceLevelID = null;
            else
            {
                if(!product.PriceLevelID.HasValue)
                    ModelState.AddModelError("PriceLevelID","You must choose PriceLevel or enter Price");
            }
            
            if (ModelState.IsValid)
            {
                db.Products.Attach(product);
                db.ObjectStateManager.ChangeObjectState(product, EntityState.Modified);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.Categories = db.Categories.Where(c => !c.ParentCategoryID.HasValue);
            ViewBag.CurrentCategoryID = product.CategoryID;
            if (product.PriceLevelID.HasValue)
                ViewBag.PriceLevelID = product.PriceLevelID;
            ViewBag.PriceLevels = db.PriceLevels;
            return View(product);
        }

        //
        // GET: /Product/Delete/5
 
        public ActionResult Delete(int id)
        {
            Product product = db.Products.Single(p => p.ProductID == id);
            return View(product);
        }

        //
        // POST: /Product/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {            
            Product product = db.Products.Single(p => p.ProductID == id);
            db.Products.DeleteObject(product);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        [HttpPost]
        public ActionResult DeleteByCategoryID(int catID)
        {
            var cat = db.Categories.Include("SubCategories").FirstOrDefault(c => c.CategoryID == catID);
            if(cat != null)
            {
                bool hasSub = cat.SubCategories.Count > 0;
                if(hasSub)
                {
                    var catSubIDs = cat.SubCategories.Select(c => c.CategoryID);
                    var pSubIDs = db.Products.Where(p => catSubIDs.Contains(p.CategoryID)).Select(p => p.ProductID);
                    foreach (int pID in pSubIDs)
                    {
                        DeleteProduct(pID);
                    }
                }
                var pIDs = db.Products.Include("ProductSizes").Where(c => c.CategoryID == catID).Select(p => p.ProductID);
                foreach (int pID in pIDs)
                {
                    DeleteProduct(pID);
                }
                ViewBag.Message = "Delete Successfull";
                db.SaveChanges();
            }
            
            return RedirectToAction("Index");
        }

        private void DeleteProduct(int pID)
        {
            Product p = db.Products.First(a => a.ProductID == pID);
            p.ProductSizes.Clear();
            List<string> files = new List<string>();
            files.Add(p.MainImage);
            files.Add(p.SmallImage);
            if (!string.IsNullOrEmpty(p.SubImage1))
                files.Add(p.SubImage1);
            if (!string.IsNullOrEmpty(p.SubImage2))
                files.Add(p.SubImage2);
            if (!string.IsNullOrEmpty(p.SubImage3))
                files.Add(p.SubImage3);
            FileInfo fi;
            foreach (string f in files)
            {
                fi = new FileInfo(Server.MapPath(f));
                if (fi.Exists)
                    fi.Delete();
            }
            db.Products.DeleteObject(p);
        }

        public ActionResult CheckProductCode(string productCode, int? productID)
        {
            bool isExist;
            if(!productID.HasValue)
                isExist = db.Products.Any(p => p.ProductCode.Trim().ToLower() == productCode.Trim().ToLower());
            else
            {
                isExist =
                    db.Products.Any(
                        p =>
                        p.ProductID != productID.Value && productCode.Trim().ToLower() == p.ProductCode.Trim().ToLower());
            }
            return Json(!isExist, JsonRequestBehavior.AllowGet);
        }
    }
}